/**********************************************************************************
// DemoBoundBox
//
// Creation:	30 Jul 2007
// Last Update: 27 May 2011
// Compiler:	Visual Studio 2010
//
// Notes:		Test the collision detection capabilities 
//				Colision of polygons using bounding boxes
**********************************************************************************/

#define WIN32_LEAN_AND_MEAN  // just say no to MFC

#include "Resources.h"
#include "Anabele.h"	

/**********************************************************************************/
/*                          BoundingBoxDemo Class                                 */
/**********************************************************************************/

typedef struct Asteroid_TYPE
{
	Poly ast;
	float vel;
} Asteroid;

/**********************************************************************************/

class BoundingBoxDemo: public D3DGame
{
private:
	Sprite * demobox;
	SceneManager sm;
	Asteroid asteroids[4];
	char text[80];
	bool viewBR;

public:
	BoundingBoxDemo();
	void InitAsteroids();

	void GameInit();
	void GameLogic();
	void GameDraw();
	void GameShutDown();
	void UnloadResources();
	void LoadResources();
};

/**********************************************************************************/

BoundingBoxDemo::BoundingBoxDemo()
{
	viewBR = false;
}

/**********************************************************************************/
void BoundingBoxDemo::InitAsteroids()
{
	Point vlist[8] = {Point(151,-154), 
						Point(179,110), 
						Point(-54,208), 
						Point(-119,94), 
						Point(-187,116), 
						Point(-225,24), 
						Point(-63,-202), 
						Point(59,-118)};
	
	asteroids[0].ast.SetVertices(vlist, 8);
	asteroids[0].ast.MoveTo(0.0f, 0.0f);

	asteroids[1].ast.SetVertices(vlist, 8);
	asteroids[1].ast.MoveTo(GetWindowWidth()-10.0f, GetWindowHeight()-1.0f);

	asteroids[2].ast.SetVertices(vlist, 8);
	asteroids[2].ast.MoveTo(GetWindowWidth()-10, 0);
	
	asteroids[3].ast.SetVertices(vlist, 8);
	asteroids[3].ast.MoveTo(0, GetWindowHeight()-1);

	for (int i=0; i<4; ++i)
	{
		asteroids[i].ast.Scale((rand()%100)*0.01f+0.2f, (rand()%100)*0.01f+0.2f);
		asteroids[i].ast.Rotate(float(rand()%360));
		asteroids[i].vel = (rand()%4)+1.0f;
	}
}

/**********************************************************************************/

void BoundingBoxDemo::GameInit()
{
	srand(GetTickCount());
	
	InitAsteroids();

	for (int i=0; i<4; ++i)
		sm.RegisterMoving(asteroids[i].ast.GetBBox());

	LoadResources();
}

/**********************************************************************************/

void BoundingBoxDemo::LoadResources()
{
	demobox = new Sprite("Resources/demoBox.png");
	demobox->MoveTo(155, 100);
}

/**********************************************************************************/

void BoundingBoxDemo::UnloadResources()
{
	if (demobox) delete demobox;
}

/**********************************************************************************/

void BoundingBoxDemo::GameShutDown()
{
	UnloadResources();
}

/**********************************************************************************/

void BoundingBoxDemo::GameLogic()
{

	// Quits by pressing ESC
	EndsOnEscape();

	// Restart Game
	if (KeyDown('R'))
		InitAsteroids();

	// Enable Bounding Rectangle
	if (KeyDown('E'))
		viewBR = true;

	// Disable Bounding Rectangle
	if (KeyDown('D'))
		viewBR = false;

	if (!sm.CollisionDetection())
	{
		asteroids[0].ast.Translate(asteroids[0].vel,asteroids[0].vel);
		asteroids[1].ast.Translate(-asteroids[1].vel,-asteroids[1].vel);
		asteroids[2].ast.Translate(-asteroids[2].vel,asteroids[2].vel);
		asteroids[3].ast.Translate(asteroids[3].vel,-asteroids[3].vel);

		asteroids[0].ast.Rotate(5);
		asteroids[1].ast.Rotate(-5);
		asteroids[2].ast.Rotate(5);
		asteroids[3].ast.Rotate(-5);
	}
} 

/**********************************************************************************/

void BoundingBoxDemo::GameDraw()
{
	// Lock screen for pixel plotting functions
	LockScreen();

	for (int i=0; i<4; i++)
	{
		// Draw polygons
		asteroids[i].ast.Draw();
				
		// Draw the bounding shape
		if (viewBR)
		{
			asteroids[i].ast.GetBBox().color = Color(235,170,35);
			asteroids[i].ast.GetBBox().Draw();
		}
	}

	UnLockScreen();	

	sprintf_s(text, "A");
	sysFont->Draw(asteroids[0].ast.IntX(), asteroids[0].ast.IntY(), text);

	sprintf_s(text, "B");
	sysFont->Draw(asteroids[1].ast.IntX(), asteroids[1].ast.IntY(), text);
	
	sprintf_s(text, "C");
	sysFont->Draw(asteroids[2].ast.IntX(), asteroids[2].ast.IntY(), text);

	sprintf_s(text, "D");
	sysFont->Draw(asteroids[3].ast.IntX(), asteroids[3].ast.IntY(), text);

	demobox->Draw();

	sprintf_s(text, "Bounding Box Demo");
	sysFont->Draw(55, 40, text);

	sprintf_s(text, "Colision Detection");
	sysFont->Draw(55, 80, text);

	sprintf_s(text, "<E> - Enable the bounding box");
	sysFont->Draw(55, 100, text);

	sprintf_s(text, "<D> - Disable the bounding box");
	sysFont->Draw(55, 120, text);

	sprintf_s(text, "<R> - Restart");
	sysFont->Draw(55, 140, text);
} 


/**********************************************************************************/
/*                                  WinMain                                       */
/**********************************************************************************/

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	BoundingBoxDemo bbdemo;

	bbdemo.SetWindowBgColor(10,25,55);
	bbdemo.SetWindowTitle(string("Bounding Box Demo"));
	bbdemo.SetWindowIcon(LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)));
	bbdemo.ShowWindowCursor(false);
	bbdemo.Initialize(hInstance);
	bbdemo.Start();
	
	return 0;

}

/**********************************************************************************/